home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Source Code / Libraries / C Internet Config / IC Component Source ƒ / IC Resource ƒ / Syslog Component ƒ / Libsprintf.c < prev    next >
Encoding:
Text File  |  1995-11-15  |  13.2 KB  |  414 lines  |  [TEXT/SPM ]

  1. dWidth) + (c - '0');
  2.         }
  3.         
  4.             /*  decode precision  */
  5.             
  6.         if (c == '.') {
  7.             if ((c = *++fmt) == '*') {
  8.                 F.precision = va_arg(arg, int);
  9.                 c = *++fmt;
  10.             } else {
  11.                 for (; c >= '0' && c <= '9'; c = *++fmt)
  12.                     F.precision = (10 * F.precision) + (c - '0');
  13.             }
  14.             if (F.precision >= 0)
  15.                 F.havePrecision = TRUE;
  16.         }
  17.         
  18.             /* decode size modifiers */
  19.             
  20.         while ((c=='h')||(c=='l')||(c=='L')){
  21.             if (c=='h')
  22.                 F.hSize=TRUE;
  23.             else if (c=='l')
  24.                 F.lSize=TRUE;
  25.             else
  26.                 F.LSize=TRUE;
  27.             
  28.             c=*++fmt;
  29.         }
  30.         
  31.             /*  perform appropriate conversion  */
  32.         
  33.         s =endbuf;
  34.         if (F.leftJustify)
  35.             F.zeroPad = FALSE;
  36.         
  37. conv:    switch (c) {
  38.                 
  39.                 /*  decimal (signed)  */
  40.                 
  41.             case 'd':
  42.             case 'i':
  43.                 if (F.lSize)
  44.                     n = va_arg(arg, long);
  45.                 else
  46.                     n = va_arg(arg, int);
  47.                 if (F.hSize)
  48.                     n = (short) n;
  49.                 if ((long) n < 0) {
  50.                     n = -n;
  51.                     F.sign = '-';
  52.                 } else if (F.forceSign)
  53.                     F.sign = '+';
  54.                 goto decimal;
  55.                 
  56.                 /*  decimal (unsigned)  */
  57.                 
  58.             case 'u':
  59.                 if (F.lSize)
  60.                     n = va_arg(arg, unsigned long);
  61.                 else
  62.                     n = va_arg(arg, unsigned int);
  63.                 if (F.hSize)
  64.                     n = (unsigned short) n;
  65.                 F.sign = 0;
  66.                 goto decimal;
  67.                 
  68.                 /*  decimal (common code)  */
  69.  
  70. decimal:
  71.                 if (!F.havePrecision) {
  72.                     if (F.zeroPad) {
  73.                         F.precision = F.fieldWidth;
  74.                         if (F.sign)
  75.                             --F.precision;
  76.                     }
  77.                     if (F.precision < 1)
  78.                         F.precision = 1;
  79.                 }
  80.                 for (i = 0; n; n /= 10, i++)
  81.                     *--s = n % 10 + '0';
  82.                 if (i<F.precision){
  83.                     j=(F.precision-i);
  84.                     s-=j;
  85.                     BlockMoveData((Ptr)__gZeroString,(Ptr)s,j);
  86.                     i=F.precision;
  87.                 }
  88.                 if (F.sign) {
  89.                     *--s = F.sign;
  90.                     i++;
  91.                 }
  92.                 break;
  93.                 
  94.                 /*  octal (unsigned)  */
  95.                 
  96.             case 'o':
  97.                 if (F.lSize)
  98.                     n = va_arg(arg, unsigned long);
  99.                 else
  100.                     n = va_arg(arg, unsigned int);
  101.                 if (F.hSize)
  102.                     n = (unsigned short) n;
  103.                 if (!F.havePrecision) {
  104.                     if (F.zeroPad)
  105.                         F.precision = F.fieldWidth;
  106.                     if (F.precision < 1)
  107.                         F.precision = 1;
  108.                 }
  109.                 for (i = 0; n; n /= 8, i++)
  110.                     *--s = n % 8 + '0';
  111.                 if (F.altForm && i && *s != '0') {
  112.                     *--s = '0';
  113.                     i++;
  114.                 }
  115.                 if (i<F.precision){
  116.                     j=(F.precision-i);
  117.                     s-=j;
  118.                     BlockMoveData((Ptr)__gZeroString,(Ptr)s,j);
  119.                     i=F.precision;
  120.                 }
  121.                 break;
  122.                 
  123.                 /*  hexadecimal (unsigned)  */
  124.                 
  125.             case 'p': // pointer processing
  126.                 F.havePrecision = F.lSize = TRUE;
  127.                 F.precision = 8;
  128.                 /* ... */
  129.             case 'X':
  130.                 digits = __gCapDigits;
  131.                 goto hexadecimal;
  132.             case 'x':
  133.                 digits =__gLowDigits;
  134.                 /* ... */
  135. hexadecimal:
  136.                 if (F.lSize)
  137.                     n = va_arg(arg, unsigned long);
  138.                 else
  139.                     n = va_arg(arg, unsigned int);
  140.                 if (F.hSize)
  141.                     n = (unsigned short) n;
  142.                 if (!F.havePrecision) {
  143.                     if (F.zeroPad) {
  144.                         F.precision = F.fieldWidth;
  145.                         if (F.altForm)
  146.                             F.precision -= 2;
  147.                     }
  148.                     if (F.precision < 1)
  149.                         F.precision = 1;
  150.                 }
  151.                 for (i = 0; n; n /= 16, i++)
  152.                     *--s = digits[n % 16];
  153.                 if (i<F.precision){
  154.                     j=(F.precision-i);
  155.                     s-=j;
  156.                     BlockMoveData((Ptr)__gZeroString,(Ptr)s,j);
  157.                     i=F.precision;
  158.                 }
  159.                 if (F.altForm) {
  160.                     *--s = c;
  161.                     *--s = '0';
  162.                     i += 2;
  163.                 }
  164.                 break;
  165.                 
  166.  
  167.                 /*  character  */
  168.                 
  169.             case 'c':
  170.                 *--s = va_arg(arg, int);
  171.                 i = 1;
  172.                 break;
  173.                 
  174.                 /*  Error  */
  175.             case 'm':
  176.                 // display the error stored in errno (s_errno);
  177.                 s=buf;
  178.                 i=libsprintf(buf,"%ld",s_errno);
  179.                 break;
  180.                 
  181.                 /*  string  */
  182.                 
  183.             case 's':
  184.                 s = va_arg(arg, char *);
  185.                 i=0;
  186.                 if (F.altForm) {
  187.                     unsigned char* ucp=(unsigned char*)s;
  188.                     unsigned char uc=*ucp;
  189.                     
  190.                     s++;
  191.                     i=(int)0;
  192.                     i+=uc;
  193.                 } else {
  194.                     i = libstrlen(s);
  195.                 }
  196.                 
  197.                 if ((F.havePrecision)&&(i>F.precision))
  198.                     i=F.precision;
  199.                 
  200.                 break;
  201.                 
  202. #ifndef _NOFLOATING_
  203.                 /*  fixed-point  */
  204.  
  205.             case 'f':
  206.                 if (F.LSize)
  207.                     x = va_arg(arg, long double);
  208.                 else
  209.                     x = va_arg(arg, double);
  210.                 if (!F.havePrecision)
  211.                     F.precision = 6;
  212.                 libf2d(1, F.precision, (LibDecRec*)&D, x);
  213.                 D.dot = D.dec.exp + D.dec.sig.length;
  214.                 if ((D.min = D.dot) > 1)
  215.                     D.min = 1;
  216.                 D.max = D.dot + F.precision;
  217.                 if (D.max - D.min > 508)
  218.                     BlockMoveData((Ptr)__gFloatConst,(Ptr)&D.dec.sig, 7);
  219.                 goto floating;
  220.  
  221.                 /*  floating-point  */
  222.                 
  223.             case 'e':
  224.             case 'E':
  225.                 if (F.LSize)
  226.                     x = va_arg(arg, long double);
  227.                 else
  228.                     x = va_arg(arg, double);
  229.                 if (!F.havePrecision)
  230.                     F.precision = 6;
  231.                 F.exponent = c;
  232.                 libf2d(0, D.max = F.precision + 1,  (LibDecRec*)&D, x);
  233.                 D.min = D.dot = 1;
  234.                 D.dec.exp += D.dec.sig.length - 1;
  235.                 goto floating;
  236.                 
  237.                 /*  "general" notation  */
  238.                 
  239.             case 'g':
  240.             case 'G':
  241.                 if (F.LSize)
  242.                     x = va_arg(arg, long double);
  243.                 else
  244.                     x = va_arg(arg, double);
  245.                 if (!F.havePrecision)
  246.                     F.precision = 6;
  247.                 else if (F.precision == 0)
  248.                     F.precision = 1;
  249.                 F.exponent = c - 2;
  250.                 libf2d(0, D.max = F.precision, (LibDecRec*) &D, x);
  251.                 D.min = D.dot = 1;
  252.                 D.dec.exp += D.dec.sig.length - 1;
  253.                 if (D.dec.exp >= -4 && D.dec.exp < F.precision) {
  254.                     F.exponent = 0;
  255.                     if ((D.dot += D.dec.exp) < 1)
  256.                         D.min = D.dot;
  257.                 }
  258.                 if (!F.altForm && D.max > D.dec.sig.length) {
  259.                     if ((D.max = D.dec.sig.length) < D.dot)
  260.                         D.max = D.dot;
  261.                 }
  262.                 goto floating;
  263.                 
  264.                     /*  floating (common code)  */
  265.  
  266. floating:
  267.                 if (D.dec.sig.text[0] > '9') {
  268.                     F.exponent = FALSE;
  269.                     D.dot = 0;
  270.                     D.min = 1;
  271.                     D.max = D.dec.sig.length;
  272.                 }
  273.                 i = 0;
  274.                 if (F.exponent) {
  275.                     n = D.dec.exp < 0 ? -D.dec.exp : D.dec.exp;
  276.                     for (; n; n /= 10, i++)
  277.                         *--s = n % 10 + '0';
  278.                     for (; i < 2; i++)
  279.                         *--s = '0';
  280.                     *--s = D.dec.exp < 0 ? '-' : '+';
  281.                     *--s = F.exponent;
  282.                     i += 2;
  283.                 }
  284.                 j = D.max;
  285.                 if (j == D.dot && !F.altForm)
  286.                     ++D.dot;
  287.                 do {
  288.                     if (j == D.dot) {
  289.                         *--s = '.';
  290.                         i++;
  291.                     }
  292.                     *--s = j > 0 && j <= D.dec.sig.length ? D.dec.sig.text[j-1] : '0';
  293.                 } while (--j >= D.min);
  294.                 i += D.max - j;
  295.                 if (D.dec.sgn)
  296.                     F.sign = '-';
  297.                 else if (F.forceSign)
  298.                     F.sign = '+';
  299.                 if (F.zeroPad) {
  300.                     j = F.fieldWidth;
  301.                     if (F.sign)
  302.                         --j;
  303.                     if (i<j){
  304.                         s -= (j-i);
  305.                         
  306.                         BlockMoveData((Ptr)__gZeroString,(Ptr)s,(j-i));
  307.                         i=j;
  308.                     }
  309.                 }
  310.                 if (F.sign) {
  311.                     *--s = F.sign;
  312.                     i++;
  313.                 }
  314.                 break;
  315. #endif /* _NOFLOATING_ */
  316.                 /*  store # bytes written so far  */
  317.                 
  318.             case 'n':
  319.                 s = (char *)va_arg(arg, void *);
  320.                 if (F.hSize)
  321.                     * (short *) s = nwritten;
  322.                 else if (F.lSize)
  323.                     * (long *) s = nwritten;
  324.                 else
  325.                     * (int *) s = nwritten;
  326.                 continue;
  327.             
  328.                 /*  oops - unknown conversion, abort  */
  329.                 
  330.             default:
  331.                 if (c != '%')
  332.                     goto done;
  333.             copy1:
  334.                 *fp=c;fp++;
  335.                 ++nwritten;
  336.                 continue;
  337.         }
  338.             
  339. EndOfSwitch:
  340.             /*  pad on the left  */
  341.             
  342.         if (i < F.fieldWidth && !F.leftJustify) {
  343.             j=F.fieldWidth-i;
  344.             
  345.             BlockMoveData((Ptr)__gSpaceString,(Ptr)fp,j);
  346.             
  347.             fp+=j;
  348.             nwritten+=j;
  349.             F.fieldWidth=0;
  350.         }
  351.         
  352.             /*  write the converted result  */
  353.         
  354.         BlockMoveData((Ptr)s,(Ptr)fp,i);
  355.         fp+=i;
  356.         nwritten += i;
  357.             
  358.             /*  pad on the right  */
  359.             
  360.         if (i<F.fieldWidth){
  361.             j=F.fieldWidth-i;
  362.             
  363.             BlockMoveData((Ptr)__gSpaceString,(Ptr)fp,j);
  364.             fp+=j;
  365.             nwritten+=j;
  366.         }
  367.     }
  368.     
  369.         /*  all done!  */
  370.         
  371. done:
  372.     *fp=0;
  373.     return nwritten;
  374. }
  375.  
  376. #ifndef _NOFLOATING_
  377.  
  378. static void post_conversion(LibDecRec *d){
  379.     int i;
  380.     /*  strip trailing zeroes  */
  381.  
  382.     for (i = d->dec.sig.length; i > 1 && d->dec.sig.text[i-1] == '0'; --i)
  383.         ++d->dec.exp;
  384.     d->dec.sig.length = i;
  385.         
  386.         /*  format 0, INF, NAN  */
  387.         
  388.     if (d->dec.sig.text[0] == '0') {
  389. /*        d->dec.sgn = 0;             add back to disallow printing "-0"  */
  390.         d->dec.exp = 0;
  391.     }
  392.     else if (d->dec.sig.text[0] == 'I') {
  393.         d->dec.sig.length = 3;
  394.         d->dec.sig.text[1] = 'N';
  395.         d->dec.sig.text[2] = 'F';
  396.     }
  397.     else if (d->dec.sig.text[0] == 'N') {
  398.         d->dec.sig.length = 5;
  399.         d->dec.sig.text[1] = 'A';
  400.         d->dec.sig.text[2] = 'N';
  401.     }
  402. }
  403.  
  404. /* ---------- floating-point conversion ---------- */
  405.  
  406. #if powerc
  407. static void libf2d( int fixed, int precision, LibDecRec *d, long double x){
  408.     struct decform form;
  409.     
  410.     if (precision >= sizeof d->dec.sig)
  411.         precision = sizeof d->dec.sig - 1;
  412.  
  413.     if (fixed)
  414.         form.style = FIX